<!-- CustomUpload.vue -->
<template>
  <div class="custom-upload-wrapper">
    <!-- 
      el-upload 组件作为功能核心:
      - :show-file-list="false" 我们自己渲染列表，所以隐藏默认的
      - :http-request="handleHttpUpload" 自定义上传逻辑
      - :on-success, :on-error, :on-exceed 处理各种事件
      - multiple 支持多选
    -->
    <el-upload
      action="#" 
      :limit="limit"
      :show-file-list="false"
      :multiple="true"
      :http-request="handleHttpUpload"
      :on-exceed="handleExceed"
    >
      <!-- 上传触发器：一个标签和一个按钮 -->
      <template #trigger>
        <div class="upload-control">
          <div class="upload-label">附件 ({{ modelValue.length }}/{{ limit }})</div>
          <el-button type="success" v-if="!readOnly">上传</el-button>
        </div>
      </template>
    </el-upload>

    <!-- 
      自定义文件列表:
      - 我们遍历 v-model 传进来的 fileVO 数组来渲染
      - 提供了加载状态和删除功能
    -->
    <div class="file-list-wrapper">
      <!-- 渲染已上传完成的文件 (来自 v-model) -->
      <div v-for="(file, index) in modelValue" :key="file.id || index" class="file-card">
        <div class="file-icon" :class="getFileIconClass(file)"></div>
        <div class="file-info">
          <div class="file-name" :title="file.name">{{ file.name }}</div>
          <div class="file-size">{{ formatFileSize(file.size) }}</div>
        </div>
        <div class="file-actions" v-if="!readOnly">
          <span class="delete-icon" @click="handleRemove(index)">×</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { ElMessage, ElButton, ElUpload, ElProgress } from 'element-plus';
import { createFileReturnVO } from '@/api/infra/file';

// --- Props & Emits for v-model ---
const props = defineProps({
  modelValue: { // v-model 绑定的 fileVO[] 数组
    type: Array,
    default: () => [],
  },
  limit: {
    type: Number,
    default: 10,
  },
  readOnly: {
    type: Boolean,
    default: false,
  },
});
const emit = defineEmits(['update:modelValue']);

// --- State ---



async function uploadFileApi(file) {  // 移除 onProgress 参数
  const formData = new FormData();
  formData.append('file', file);

  try {
    const response = await createFileReturnVO(formData);
    return response.data;  // 假设接口返回 { data: fileVO }
  } catch (error) {
    throw new Error('文件上传失败：' + (error.message || '未知错误'));
  }
}



const handleHttpUpload = async (options) => {
  const { file } = options;

  try {
    // 直接调用上传接口（无需处理进度）
    const fileVO = await uploadFileApi(file);
    console.log('接口调用成功:', fileVO);  // 打印上传成功的 fileVO
    
    handleSuccess(fileVO);  
  } catch (error) {
    handleError(error);
  }
};

/**
 * 上传成功回调
 * @param {object} fileVO - 从 handleHttpUpload 中传递过来的后端返回的 fileVO
 */
const handleSuccess = (fileVO) => {  
  console.log('上传成功:', fileVO);  // 打印上传成功的 fileVO
  if (!fileVO) {
    ElMessage.error('文件上传成功但未获取到文件信息');
    return;
  }

  const updatedList = [...props.modelValue, fileVO];
  emit('update:modelValue', updatedList);
  ElMessage.success(`${fileVO.name} 上传成功`);
};
/**
 * 上传失败回调
 */
const handleError = (error) => {
  console.error('上传失败:', error);
  ElMessage.error('文件上传失败，请稍后重试。');
};

/**
 * 文件数量超出限制回调
 */
const handleExceed = () => {
  ElMessage.warning(`最多只能上传 ${props.limit} 个文件。`);
};

/**
 * 自定义删除方法
 * @param {number} index - 要删除的文件在 v-model 数组中的索引
 */
const handleRemove = (index) => {
  const fileToRemove = props.modelValue[index];
  const updatedList = props.modelValue.filter((_, i) => i !== index);
  emit('update:modelValue', updatedList);
  ElMessage.info(`文件 ${fileToRemove.name} 已被移除`);
};

// --- Helper Functions ---
const formatFileSize = (bytes) => {
  if (!bytes) return '0 Bytes';
  const k = 1024;
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + ['Bytes', 'KB', 'MB', 'GB'][i];
};

const getFileIconClass = (file) => {
  const extension = file.name.split('.').pop().toLowerCase();
  if (['xls', 'xlsx'].includes(extension)) return 'icon-excel';
  if (['png', 'jpg', 'jpeg', 'gif', 'bmp', 'dwg', 'svg'].includes(extension)) return 'icon-image';
  return 'icon-generic';
};
</script>

<style scoped>
/* 主容器和触发器布局 */
.custom-upload-wrapper {
  display: flex;
  align-items: flex-start;
  gap: 20px;
  width: 100%;
}

.upload-control {
  flex-shrink: 0;
  text-align: center;
}

.upload-label {
  margin-bottom: 15px;
  font-size: 14px;
  color: #606266;
}

/* 文件列表和卡片样式 (与你截图的样式一致) */
.file-list-wrapper {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
  flex-grow: 1;
}

.file-card {
  position: relative;
  display: flex;
  width: 220px;
  padding: 10px;
  background-color: #fff;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  align-items: center;
}

.file-card.is-uploading {
  opacity: 0.7;
}

.file-info {
  width: 100%; /* 让进度条撑满 */
  margin-left: 10px;
  overflow: hidden;
}

.file-name {
  overflow: hidden;
  font-size: 14px;
  color: #303133;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-size {
  font-size: 12px;
  color: #909399;
}

/* 删除图标 */
.file-actions {
  position: absolute;
  top: -8px;
  right: -8px;
  opacity: 0;
  transition: opacity 0.3s;
}

.file-card:hover .file-actions {
  opacity: 1;
}

.delete-icon {
  display: flex;
  width: 18px;
  height: 18px;
  font-size: 14px;
  line-height: 18px;
  color: white;
  cursor: pointer;
  background-color: rgb(0 0 0 / 40%);
  border-radius: 50%;
  justify-content: center;
  align-items: center;
}

.delete-icon:hover {
  background-color: rgb(0 0 0 / 60%);
}

/* 文件类型图标 */
.file-icon {
  position: relative;
  width: 32px;
  height: 40px;
  background-color: #f0f0f0;
  border: 1px solid #ccc;
  border-radius: 4px;
  flex-shrink: 0;
}

.file-icon::before {
  position: absolute;
  top: -1px;
  right: -1px;
  width: 0;
  height: 0;
  border-bottom: 12px solid #fff;
  border-left: 12px solid transparent;
  content: '';
}

.file-icon.icon-excel::after { font-weight: bold; color: #1f7845; content: 'X'; }

.file-icon.icon-image::after { font-weight: bold; color: #409eff; content: 'IMG'; }

.file-icon.icon-generic::after { font-weight: bold; letter-spacing: -2px; color: #606266; content: '...'; }

.file-icon::after {
  position: absolute;
  top: 50%;
  left: 50%;
  font-size: 14px;
  transform: translate(-50%, -50%);
}
</style>